<!DOCTYPE HTML>
<html>

<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="../bootstrap.min.css" rel="stylesheet">
    <link href="../cornerstone.min.css" rel="stylesheet">
</head>

<body>
    <div class="container">
        <div class="page-header">
            <h1>Example of displaying progressive resolution HTJ2K DICOM P10 image using Cornerstone</h1>
        </div>
        <br>
        <div id="viewports">

        </div>
        <br>
        <!-- <div class="row">
            <div class="col-md-6">
                <div style="width:512px;height:512px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;"
                    oncontextmenu="return false" class='disable-selection noIbar' unselectable='on'
                    onselectstart='return false;' onmousedown='return false;'>
                    <div id="dicomImage" style="width:512px;height:512px;top:0px;left:0px; position:absolute">
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <span>Transfer Syntax: </span><span id="transferSyntax"></span><br>
                <span>SOP Class: </span><span id="sopClass"></span><br>
                <span>Samples Per Pixel: </span><span id="samplesPerPixel"></span><br>
                <span>Photometric Interpretation: </span><span id="photometricInterpretation"></span><br>
                <span>Number Of Frames: </span><span id="numberOfFrames"></span><br>
                <span>Planar Configuration: </span><span id="planarConfiguration"></span><br>
                <span>Rows: </span><span id="rows"></span><br>
                <span>Columns: </span><span id="columns"></span><br>
                <span>Pixel Spacing: </span><span id="pixelSpacing"></span><br>
                <span>Row Pixel Spacing: </span><span id="rowPixelSpacing"></span><br>
                <span>Column Pixel Spacing: </span><span id="columnPixelSpacing"></span><br>
                <span>Bits Allocated: </span><span id="bitsAllocated"></span><br>
                <span>Bits Stored: </span><span id="bitsStored"></span><br>
                <span>High Bit: </span><span id="highBit"></span><br>
                <span>Pixel Representation: </span><span id="pixelRepresentation"></span><br>
                <span>WindowCenter: </span><span id="windowCenter"></span><br>
                <span>WindowWidth: </span><span id="windowWidth"></span><br>
                <span>RescaleIntercept: </span><span id="rescaleIntercept"></span><br>
                <span>RescaleSlope: </span><span id="rescaleSlope"></span><br>
                <span>Basic Offset Table Entries: </span><span id="basicOffsetTable"></span><br>
                <span>Fragments: </span><span id="fragments"></span><br>
                <span>Max Stored Pixel Value: </span><span id="minStoredPixelValue"></span><br>
                <span>Min Stored Pixel Value: </span><span id="maxStoredPixelValue"></span><br>
                <span>Total Time: </span><span id="totalTime"></span><br>
                <span>Load Time: </span><span id="loadTime"></span><br>
                <span>Decode Time: </span><span id="decodeTime"></span><br>
            </div>
        </div> -->
    </div>
</body>

<!-- include the cornerstone library -->
<script src="../cornerstone.min.js"></script>
<SCRIPT src="../cornerstoneMath.min.js"></SCRIPT>
<SCRIPT src="../cornerstoneTools.min.js"></SCRIPT>

<!-- include the dicomParser library as the WADO image loader depends on it -->
<script src="../dicomParser.min.js"></script>

<!-- include the cornerstoneDICOMImageLoader library -->
<script src="../dist/cornerstoneDICOMImageLoader.bundle.min.js"></script>

<script src="../dicomfile/uids.js"></script>
<script src="../utils/initializeWebWorkers.js"></script>

<script>

    // Used `fetch` api here just for simplicity. No reason this functionality
    // can't be integrated into the existing xhrRequest.js fuction so that all
    // the other default functionality like progress events also work.
    async function request(url, imageId, options = { byteRange: '0-100000' }) {
        const { byteRange } = options;

        const headers = new Headers({
            'Range': `bytes=${byteRange}`,
        });

        try {
            const response = await fetch(url, { headers });
            const partialFileArrayBuffer = await response.arrayBuffer();
            const contentRange = response.headers.get('content-range');
            const fileTotalLength = parseInt(contentRange.split('/')[1])

            return { arrayBuffer: partialFileArrayBuffer, flags: { isPartialContent: true, fileTotalLength } };
        } catch (err) {
            console.error(err);
        }
    }

    cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;

    const baseUrls = [
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/1.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-1.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-2.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-3.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-4.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-5.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-6.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-7.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-8.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-9.jph.dcm',
        'https://pacsbin-util.s3.amazonaws.com/test-images/htj2k/xray-10.jph.dcm',
    ];

    const urls = [];
    const cachebust = true;

    for (let i = 0; i < 20; i += 1) {
        let url = baseUrls[i % 11];
        if (cachebust) {
            url += '?cachebust=' + (Math.random() + 1).toString(36).substring(7);
        }
        urls.push(url)
    }

    urls.forEach(url => {
        // Create element
        const viewportContainer = document.getElementById('viewports');
        const viewportDiv = document.createElement('div');
        viewportDiv.classList = 'disable-selection noIbar'
        viewportDiv.style = 'width:200px;height:200px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;'
        viewportDiv.onmousedown = 'return false;'
        const canvasDiv = document.createElement('div');
        canvasDiv.style = 'width:200px;height:200px;';

        viewportDiv.append(canvasDiv)
        viewportContainer.append(viewportDiv)

        const element = canvasDiv;
        cornerstone.enable(element);
        const imageId = `wadouri:${url}`;
        let loaded = false;

        canvasDiv.onmouseover = () => {
            canvasDiv.style.position = 'absolute'
            canvasDiv.style.width = '512px'
            canvasDiv.style.height = '512px'
            canvasDiv.style.zIndex = '10';
            cornerstone.resize(element, true);
        }
        canvasDiv.onmouseout = () => {
            canvasDiv.style.position = 'relative';
            canvasDiv.style.width = '200px'
            canvasDiv.style.height = '200px'
            canvasDiv.style.zIndex = '1';
            cornerstone.resize(element, true);
        }

        // Load more of the image on click
        canvasDiv.addEventListener('click', async function (e) {
            const ee = cornerstone.getEnabledElement(element);
            const { sharedCacheKey: uri } = ee.image;
            const dataSet = cornerstoneDICOMImageLoader.wadouri.dataSetCacheManager.get(uri);

            const newDataSet = await dataSet.fetchMore({
                lengthToFetch: 500000,
            });

            console.log(newDataSet);

            // Not sure how much of this should be handled automatically inside
            // cornerstoneDICOMImageLoader, vs explicitly in user scripts. It
            // would probably be helpful for everything below here to be one
            // function call or automatic upon invoking `fetchMore`.
            cornerstoneDICOMImageLoader.wadouri.dataSetCacheManager.update(uri, newDataSet)

            const imageId = "wadouri:" + uri;

            cornerstone.imageCache.removeImageLoadObject(imageId)
            cornerstone.loadAndCacheImage(imageId).then((image) => {
                cornerstone.invalidate(element);
                cornerstone.displayImage(element, image)
            })
        });

        try {
            var start = new Date().getTime();
            cornerstone.loadAndCacheImage(imageId, { loader: request }).then(function (image) {
                console.log(image);
                var viewport = cornerstone.getDefaultViewportForImage(element, image);
                // document.getElementById('toggleModalityLUT').checked = (viewport.modalityLUT !== undefined);
                // document.getElementById('toggleVOILUT').checked = (viewport.voiLUT !== undefined);
                cornerstone.displayImage(element, image, viewport);
                if (loaded === false) {
                    cornerstoneTools.mouseInput.enable(element);
                    cornerstoneTools.mouseWheelInput.enable(element);
                    cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button
                    cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
                    cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
                    cornerstoneTools.zoomWheel.activate(element); // zoom is the default tool for middle mouse wheel
                    loaded = true;
                }

                function getTransferSyntax() {
                    const value = image.data.string('x00020010');
                    return value + ' [' + uids[value] + ']';
                }

                function getSopClass() {
                    const value = image.data.string('x00080016');
                    return value + ' [' + uids[value] + ']';
                }

                function getPixelRepresentation() {
                    const value = image.data.uint16('x00280103');
                    if (value === undefined) {
                        return;
                    }
                    return value + (value === 0 ? ' (unsigned)' : ' (signed)');
                }

                function getPlanarConfiguration() {
                    const value = image.data.uint16('x00280006');
                    if (value === undefined) {
                        return;
                    }
                    return value + (value === 0 ? ' (pixel)' : ' (plane)');
                }


                // document.getElementById('transferSyntax').textContent = getTransferSyntax();
                // document.getElementById('sopClass').textContent = getSopClass();
                // document.getElementById('samplesPerPixel').textContent = image.data.uint16('x00280002');
                // document.getElementById('photometricInterpretation').textContent = image.data.string('x00280004');
                // document.getElementById('numberOfFrames').textContent = image.data.string('x00280008');
                // document.getElementById('planarConfiguration').textContent = getPlanarConfiguration();
                // document.getElementById('rows').textContent = image.data.uint16('x00280010');
                // document.getElementById('columns').textContent = image.data.uint16('x00280011');
                // document.getElementById('pixelSpacing').textContent = image.data.string('x00280030');
                // document.getElementById('rowPixelSpacing').textContent = image.rowPixelSpacing;
                // document.getElementById('columnPixelSpacing').textContent = image.columnPixelSpacing;
                // document.getElementById('bitsAllocated').textContent = image.data.uint16('x00280100');
                // document.getElementById('bitsStored').textContent = image.data.uint16('x00280101');
                // document.getElementById('highBit').textContent = image.data.uint16('x00280102');
                // document.getElementById('pixelRepresentation').textContent = getPixelRepresentation();
                // document.getElementById('windowCenter').textContent = image.data.string('x00281050');
                // document.getElementById('windowWidth').textContent = image.data.string('x00281051');
                // document.getElementById('rescaleIntercept').textContent = image.data.string('x00281052');
                // document.getElementById('rescaleSlope').textContent = image.data.string('x00281053');
                // document.getElementById('basicOffsetTable').textContent = image.data.elements.x7fe00010.basicOffsetTable ? image.data.elements.x7fe00010.basicOffsetTable.length : '';
                // document.getElementById('fragments').textContent = image.data.elements.x7fe00010.fragments ? image.data.elements.x7fe00010.fragments.length : '';
                // document.getElementById('minStoredPixelValue').textContent = image.minPixelValue;
                // document.getElementById('maxStoredPixelValue').textContent = image.maxPixelValue;
                // var end = new Date().getTime();
                // var time = end - start;
                // document.getElementById('totalTime').textContent = time + "ms";
                // document.getElementById('loadTime').textContent = image.loadTimeInMS + "ms";
                // document.getElementById('decodeTime').textContent = image.decodeTimeInMS + "ms";

            }, function (err) {
                throw err;
            });
        }
        catch (err) {
            throw err;
        }

    })

    cornerstone.events.addEventListener('cornerstoneimageloadprogress', function (event) {
        const eventData = event.detail;
        const loadProgress = document.getElementById('loadProgress');
        loadProgress.textContent = `Image Load Progress: ${eventData.percentComplete}%`;
    });

    function getUrlWithoutFrame() {
        var url = document.getElementById('wadoURL').value;
        var frameIndex = url.indexOf('frame=');
        if (frameIndex !== -1) {
            url = url.substr(0, frameIndex - 1);
        }
        return url;
    }
</script>

</html>
